package aisLogic;

import java.util.Observable;
import java.util.Observer;
import java.util.LinkedList;

public class Frame extends Observable implements Observer
{
	public static final int NULL = -1;
	public static final int ACTION = NULL + 1;
	public static final int INDEX = ACTION + 1;
	public static final int ARRAY_SIZE = INDEX + 1;
	
	public static final int ADD_MODULE_REF = 0;
	public static final int REMOVE_MODULE_REF = ADD_MODULE_REF + 1;
	public static final int REMOVE_MODULE_REF_MODULE = REMOVE_MODULE_REF + 1; 
	public static final int UPDATE_MODULE_REF_ATT_DX = REMOVE_MODULE_REF_MODULE + 1; 
	public static final int UPDATE_MODULE_REF_ATT_DY = UPDATE_MODULE_REF_ATT_DX + 1;
	public static final int UPDATE_MODULE_REF_ATT_MODULE = UPDATE_MODULE_REF_ATT_DY + 1; 
	
	
	private LinkedList<ModuleRef> moduleRef = new LinkedList<ModuleRef>();
	

	public Frame()
	{
		super();
	}

	public int getSize()
	{
		return this.moduleRef.size();
	}
	
	
	public Object[] notifyArray(int action, int index)
	{
		Object ao[] = new Object[ARRAY_SIZE];
		ao[ACTION] = new Integer(action);
		ao[INDEX] = new Integer(index);
		return ao;
	}
	
	public void addModuleRef(ModuleRef m)
	{
		m.addObserver(this);
		this.moduleRef.add(m);
		this.setChanged();
		this.notifyObservers(this.notifyArray(ADD_MODULE_REF, this.moduleRef.indexOf(m)));
	}
	
	public void removeModuleRef(int index)
	{
		this.moduleRef.remove(index);
		this.setChanged();
		this.notifyObservers(this.notifyArray(REMOVE_MODULE_REF, index));
	}
	
	public ModuleRef getModuleRef(int index)
	{
		return (ModuleRef)this.moduleRef.get(index);
	}
	
	public int getModuleRefId(ModuleRef mr)
	{
		int ret = -1;
		for( int i = 0; i < this.moduleRef.size(); i++)
		{
			ModuleRef m = this.moduleRef.get(i);
			if(m == mr) ret = i;
		}
		return ret;
	}
	
	public void updateModuleRef(int index, int attModuleRef, int value)
	{
		ModuleRef mr = this.getModuleRef(index);
		int action = (attModuleRef == ModuleRef.DX)? UPDATE_MODULE_REF_ATT_DX : UPDATE_MODULE_REF_ATT_DY;
		switch(attModuleRef)
		{
			case ModuleRef.DX:
				mr.setDx(value);
				break;
			case ModuleRef.DY:
				mr.setDy(value);
			default:
				return;
		}
		this.setChanged();
		this.notifyObservers(this.notifyArray(action, index));
	}
	
	public ModuleRef[] getModuleRef(int from, int to)
	{
		ModuleRef[] m = new ModuleRef[to-from];
		for(int i = 0; i<(to -from); i++)
		{
			m[i] = this.getModuleRef(to + i);
		}
		return m;
	}
	
	public ModuleRef[] getAllModuleRef()
	{
		return this.getModuleRef(0, this.getSize());
	}
	
	public void removeModule(Module m)
	{
		for(int i = 0; i< this.moduleRef.size(); i++)
		{
			ModuleRef mr = this.getModuleRef(i); 
			Module m2 = mr.getModule();
			if(m == m2)
			{
				mr.setModule(null);
			}
		}
	}
	
	public void update(Observable o, Object arg)
	{
		ModuleRef mr = (ModuleRef)o;
		Integer d = (Integer)arg;
		int index = NULL;
		int action = NULL; 
		
		for(int i = 0; i< this.moduleRef.size(); i++)
		{
			if(mr == (ModuleRef)this.moduleRef.get(i))
			{
				index = i;
			}
		}
		
		switch(d.intValue())
		{
			case ModuleRef.DX: 
				action = UPDATE_MODULE_REF_ATT_DX;
				break;
			case ModuleRef.DY:
				action = UPDATE_MODULE_REF_ATT_DY;
				break;
			case ModuleRef.MODULE:
				action = UPDATE_MODULE_REF_ATT_MODULE;
		}
		
		this.setChanged();
		this.notifyObservers(this.notifyArray(action, index));
	}

}
